package com.tanhua.sso.service;

import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tanhua.sso.config.AliyunSMSConfig;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
/**
 * @ClassName :  UserMapper
 * @Author : Tenebrous
 * @Date: 2020/12/7 20:34
 * @Description : 发送短信
 */
@Service
public class SmsService {

    /**
     *  日志
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(SmsService.class);

    /**
     *  restTemplate
     */
    @Autowired
    private RestTemplate restTemplate;

    private static final ObjectMapper MAPPER = new ObjectMapper();

    /**
     * redis模板
     */
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private AliyunSMSConfig aliyunSmsConfig;

    public static final String REDIS_KEY_PREFIX = "CHECK_CODE_";

    /**
     * 发送验证码
     * @param mobile 手机号码
     * @return 返回状态码和状态信息
     */
    public Map<String, Object> sendCheckCode(String mobile) {
        Map<String, Object> result = new HashMap<>(2);
        try {
            // 拼接redis的key
            String redisKey = REDIS_KEY_PREFIX + mobile;
            // 通过模板去获取redis的key
            String value = this.redisTemplate.opsForValue().get(redisKey);
            redisTemplate.delete(redisKey);
            // 如果字符串value 不为空，并且长度大于0，说明redis中存在，验证码还未失效
            if (StringUtils.isNotEmpty(value)) {
                // 将状态码和信息保存到map集合中，并返回
                result.put("code", 1);
                result.put("msg", "上一次发送的验证码还未失效");
                return result;
            }
           // 调用阿里云的短信验证码服务
//            String code = this.sendSmsAliyun(mobile);
            String code = "123456";
            // 如果验证码为null
            if (null == code) {
                // 返回状态码为2，发送失败
                result.put("code", 2);
                result.put("msg", "发送短信验证码失败");
                return result;
            }
            // 否则发送验证码成功
            result.put("code", 3);
            result.put("msg", "ok");
            //将验证码存储到Redis,2分钟后失效
            this.redisTemplate.opsForValue().set(redisKey, code, Duration.ofMinutes(2));
            return result;
        } catch (Exception e) {
            LOGGER.error("发送验证码出错！" + mobile, e);
            result.put("code", 4);
            result.put("msg", "发送验证码出现异常");
            return result;
        }

    }

    /**
     * 云之讯 发送验证码短信
     *
     * @param mobile 手机号码
     */
    public String sendSms(String mobile) {
        String url = "https://open.ucpaas.com/ol/sms/sendsms";
        // 创建map集合，将所需要的参数填充
        Map<String, Object> params = new HashMap<>(6);
        params.put("sid", "3d9dce422faf81c4f96f1ee38b0622fb");
        params.put("token", "ce1b86bb09005b593f9a730bb6c60e5f");
        params.put("appid", "e6c5f94bd9754bd7864a5278c097eea4");
        params.put("templateid", "564827");
        params.put("mobile", mobile);
        // 生成6位数验证
        params.put("param", RandomUtils.nextInt(100000, 999999));
        // post请求
        ResponseEntity<String> responseEntity = this.restTemplate.postForEntity(url, params, String.class);
        String body = responseEntity.getBody();
        try {
            // 对body进行解析
            JsonNode jsonNode = MAPPER.readTree(body);
            //如果 code是000000 表示发送成功
            if (StringUtils.equals(jsonNode.get("code").textValue(), "000000")) {
                // 返回验证码
                return String.valueOf(params.get("param"));
            }
            LOGGER.error(jsonNode.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;

    }

    /**
     * 通过阿里云发送验证码短信
     *
     * @param mobile 手机号码
     */
    public String sendSmsAliyun(String mobile) {
        DefaultProfile profile = DefaultProfile.getProfile(
                this.aliyunSmsConfig.getRegionId(),
                this.aliyunSmsConfig.getAccessKeyId(),
                this.aliyunSmsConfig.getAccessKeySecret());
        IAcsClient client = new DefaultAcsClient(profile);

        String code = RandomUtils.nextInt(100000, 999999) +"";

        CommonRequest request = new CommonRequest();
        request.setSysMethod(MethodType.POST);
        request.setSysDomain(this.aliyunSmsConfig.getDomain());
        request.setSysVersion("2017-05-25");
        request.setSysAction("SendSms");
        request.putQueryParameter("RegionId", this.aliyunSmsConfig.getRegionId());
        request.putQueryParameter("PhoneNumbers", mobile);
        request.putQueryParameter("SignName", this.aliyunSmsConfig.getSignName());
        request.putQueryParameter("TemplateCode", this.aliyunSmsConfig.getTemplateCode());
        request.putQueryParameter("TemplateParam", "{\"code\":\""+code+"\"}");
        try {
            CommonResponse response = client.getCommonResponse(request);
            String data = response.getData();
            System.out.println(data);
            if(StringUtils.contains(response.getData(), "\"Code\":\"OK\"")){
                return code;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}